
#include "app_includes.h"

/**
  * @brief  this function handles usart2 receive data.
  * @param  none
  * @retval the data len
  */
uint16_t usart_receive_data(void)
{
  uint16_t usart_data_len;
  if(board.cdc.usart_read_index == board.cdc.usart_rx_index)
  {
    usart_data_len = 0;
  }
  else
  {
    /* whether to process the fifo overflow or not */
    if(board.cdc.usart_rx_index > board.cdc.usart_read_index)
      usart_data_len = board.cdc.usart_rx_index - board.cdc.usart_read_index;
    else if(board.cdc.usart_rx_index == 0 && board.cdc.usart_rx_index != board.cdc.usart_read_index)
      usart_data_len = BSP_CDC_USART_RX_BUFF_SIZE - board.cdc.usart_read_index;
    else
      usart_data_len = (BSP_CDC_USART_RX_BUFF_SIZE-1) + board.cdc.usart_rx_index - board.cdc.usart_read_index;
  }

  return usart_data_len;
}

void task_cdc(void *para)
{
      uint16_t data_len;

      uint32_t timeout;

      uint8_t send_zero_packet = 0;
    uint16_t ov_cnt = 0;
    while(1)
    {
        /* get usb vcp receive data */
        data_len = usb_vcp_get_rxdata(&board.cdc.usb_core_dev, board.cdc.usb_buffer);

        /* send data to hardware usart */
        if(data_len > 0)
        {
          board_serial_send(0, (char *)board.cdc.usb_buffer, data_len);
        }

        /* if hardware usart received data,usb send data to host */
        board.cdc.usart_rx_data_len = usart_receive_data();
        if(board.cdc.usart_rx_data_len || send_zero_packet == 1)
        {
          if(board.cdc.usart_rx_data_len > 0)
            send_zero_packet = 1;

          if(board.cdc.usart_rx_data_len == 0)
            send_zero_packet = 0;

          timeout = 50000;

          if((board.cdc.usart_read_index + board.cdc.usart_rx_data_len) < BSP_CDC_USART_RX_BUFF_SIZE)
          {
            do
            {
              /* send data to host */
              if(usb_vcp_send_data(&board.cdc.usb_core_dev, &board.cdc.usart_rx_buffer[board.cdc.usart_read_index], board.cdc.usart_rx_data_len) == SUCCESS)
              {
                board.cdc.usart_read_index = board.cdc.usart_read_index + board.cdc.usart_rx_data_len;

                break;
              }
            }while(timeout --);

          }
          /* process the fifo overflow */
          else
          {
            do
            {
              /* send data to host */
              if(usb_vcp_send_data(&board.cdc.usb_core_dev, &board.cdc.usart_rx_buffer[board.cdc.usart_read_index], BSP_CDC_USART_RX_BUFF_SIZE - board.cdc.usart_read_index) == SUCCESS)
              {
                /* get fifo overflow data count */
                ov_cnt = board.cdc.usart_rx_data_len - (BSP_CDC_USART_RX_BUFF_SIZE - board.cdc.usart_read_index);
                board.cdc.usart_read_index = 0;
                break;
              }
            }while(timeout --);
            timeout = 50000;
            do
            {
              /* send data to host */
              if(usb_vcp_send_data(&board.cdc.usb_core_dev, &board.cdc.usart_rx_buffer[board.cdc.usart_read_index], ov_cnt) == SUCCESS)
              {
                board.cdc.usart_read_index = ov_cnt;
                break;
              }
            }while(timeout --);
          }
        }
        
        vTaskDelay(pdMS_TO_TICKS(10));
      }
}
